package com.suning.sawp.web.controller;

import java.security.Principal;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.constants.LoggerConstants;
import com.suning.sawp.constants.PreChargeErrorConstants;
import com.suning.sawp.constants.PromotionErrorConstants;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.customer.CustRemarkInfoRtn;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.dto.precharge.CommonRtn;
import com.suning.sawp.dto.sys.StoreManBindDeviceInfo;
import com.suning.sawp.dto.sys.UserInfo;
import com.suning.sawp.intf.bind.BindDeviceService;
import com.suning.sawp.intf.bind.dto.BindRecordDto;
import com.suning.sawp.intf.customer.CustRemarkService;
import com.suning.sawp.intf.model.ModelErrorConstant;
import com.suning.sawp.intf.storeman.StoreManService;
import com.suning.sawp.intf.sys.SystemService;
import com.suning.sawp.service.util.AESUtils;
import com.suning.sawp.service.util.BaseContants;
import com.suning.sawp.service.util.ConfigUtil;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.service.util.GsonUtils;
import com.suning.sawp.service.util.SCMConfigUtil;
import com.suning.sawp.web.exception.MobileException;
import com.suning.sawp.web.exception.MyGsonView;
import com.suning.vgs.follow.remote.store.StoreManMoible;

/**
 * 系统管理controller
 * 
 * @author 14062606
 * @see [相关类/方法]
 * @since 
 */
@Controller
@RequestMapping("/sys")
public class SystemController extends DjBaseController{
	
	private static final Logger LOGGER = LoggerFactory.getLogger(LoggerConstants.SAWP_SERVICE);
	
	@Autowired
	SystemService systemService;
	
	@Autowired
	CustRemarkService custRemarkService;
	
	@Autowired
	BindDeviceService bindDeviceService;
	
	@Resource
    StoreManService storeManService;
	
	/**
     * 
     * 功能描述: 查询用户信息<br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
	@RequestMapping("/queryUserInfo.do")
    @ResponseBody
	public String queryUserInfo(Principal principal){
		// 获取当前用户id，即工号
		String userId = principal.getName();
		LOGGER.debug("开始更新职员信息，userId=" + userId);
        ReturnMsg<UserInfo> ret = new ReturnMsg<UserInfo>();
        try{
        	ret = systemService.queryUserInfo(userId);
        } catch (Exception e){
        	LOGGER.error("更新职员信息失败，userId="+userId+",error="+e);
        	ret.setRetFlag(ReturnMsg.FAIL);
            ret.setErrorCode(PromotionErrorConstants.ACT_QUERY_ERR_E999);
            ret.setErrorMessage(PromotionErrorConstants.ACT_QUERY_ERR_MAP
                    .get(PromotionErrorConstants.ACT_QUERY_ERR_E999));
        }
        
		return GsonUtils.toJson(ret,false);
	}
	
	/**
     * 
     * 功能描述: 查询客户名片信息<br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
	@RequestMapping("/queryCustInfo.do")
	public MyGsonView queryCustInfo(String custNum, Principal principal) throws MobileException{
		
		//解密客户编码
        String custNo = AESUtils.decrypt(custNum, ConfigConstants.AES_KEY);
        //解密失败,抛异常
        if (StringUtils.isBlank(custNo)) {
            LOGGER.error("查询客户名片信息.custNum解密异常,custNum="+custNum);
            MessageFormat form = new MessageFormat(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0004));
            throw new MobileException(ErrorCodeConstants.ERR_0004, form.format(new String[]{"custNo"}));
        }
        MyGsonView gsonView = createGsonView();
		// 获取当前用户id，即工号
		String userId = principal.getName();
		LOGGER.info("开始查询客户名片信息,custNo="+custNo+",userId="+userId);
		ReturnMsg<CustRemarkInfoRtn> custInfo = new ReturnMsg<CustRemarkInfoRtn>();
		try {
			custInfo = custRemarkService.queryCustInfoByCustNum(custNo,userId);
		} catch (Exception e) {
			custInfo.setRetFlag(ReturnMsg.FAIL);
			custInfo.setErrorCode(PreChargeErrorConstants.PRECHARGE_ERR_E999);
			custInfo.setErrorMessage(PreChargeErrorConstants.PRECHARGE_ERR_MAP
                    .get(PreChargeErrorConstants.PRECHARGE_ERR_E999));
			LOGGER.error("查询客户名片信息失败，custNum="+custNum+",custNo="+custNo+",userId="+userId+",error="+e);
		}
		gsonView.addStaticAttribute("ret", custInfo);
        gsonView.setJsonObjectName("ret");
		return gsonView;
	}

	/**
     * 
     * 功能描述: 记录客户备注信息<br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
	@RequestMapping("/saveCustRemarkInfo.do")
	public MyGsonView saveCustRemarkInfo(Principal principal, String custNum, String commodityName,
			String hopePrice, String hopeBuyDate, String remark, String tag) throws MobileException{
		Date hopeDate = null;
		try {
            SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.DEFAULT_DATE_PATTERN);
            //预计购买时间
            if (StringUtils.isNotBlank(hopeBuyDate)) {
                hopeDate = sdf.parse(hopeBuyDate);
            }
        } catch (Exception e) {
            LOGGER.error("记录客户备注信息.hopeBuyDate转换异常,hopeBuyDate="+hopeBuyDate, e);
            MessageFormat form = new MessageFormat(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0004));
            throw new MobileException(ErrorCodeConstants.ERR_0004, form.format(new String[]{"callTime"}));
        }
		
		//解密客户编码
        String custNo = AESUtils.decrypt(custNum, ConfigConstants.AES_KEY);
        //解密失败,抛异常
        if (StringUtils.isBlank(custNo)) {
            LOGGER.error("记录客户备注信息.custNum解密异常,custNum="+custNum);
            MessageFormat form = new MessageFormat(ErrorCodeConstants.ERR_MAP.get(ErrorCodeConstants.ERR_0004));
            throw new MobileException(ErrorCodeConstants.ERR_0004, form.format(new String[]{"custNo"}));
        }
		
        MyGsonView view = createGsonView();
		// 获取当前用户id，即工号
		String userId = principal.getName();
		LOGGER.info("开始记录客户备注信息,custNo="+custNo+",userId="+userId+",commodityName="+
				commodityName+",hopePrice="+hopePrice+",hopeBuyDate="+hopeBuyDate+
				",remark="+remark+",tag="+tag);
		try {
			custRemarkService.saveCustRemarkInfo(userId, custNo, commodityName,
					hopePrice, hopeDate, remark, tag);
		} catch (Exception e) {
			view.addStaticAttribute(BaseContants.RET_FLAG, BaseContants.FAILED);
			view.addStaticAttribute(BaseContants.ERROR_CODE, PreChargeErrorConstants.PRECHARGE_ERR_E999);
			view.addStaticAttribute(BaseContants.ERROR_MSG, PreChargeErrorConstants.PRECHARGE_ERR_MAP
                    .get(PreChargeErrorConstants.PRECHARGE_ERR_E999));
			LOGGER.error("记录客户备注信息失败，custNum="+custNum+",custNo="+custNo+",userId="+userId+",error="+e);
		}
		return view;
	}
	
	/**
	 * 
	 * 功能描述: 获取千里传音地址<br>
	 * 〈功能详细描述〉
	 *
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	@RequestMapping("/getVoipUrl.do")
	public MyGsonView getVoipUrl() {
	    MyGsonView view = createGsonView();
	    String url = ConfigUtil.getConfig("/config/sawp/config", "voipUrl");
	    view.addStaticAttribute(BaseContants.DATA, url);
	    return view;
	}
	
	/**
	 * 
	 * 功能描述: 校验设备ID<br>
	 * 〈功能详细描述〉
	 *
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	@RequestMapping("/validDeviceId.do")
	public MyGsonView validDeviceId(Principal principal, String djDeviceId) {
	    ReturnMsg<CommonRtn> ret = new ReturnMsg<CommonRtn>();
	    
		String staffId = principal.getName();
		
	    // 解密客户端传过来的加密设备ID
        String reqDeviceId = AESUtils.decodeAndDecrypt(djDeviceId, ConfigConstants.AES_KEY);
        LOGGER.info("ValidDeviceFilter validDevice staffId:{}, deviceId:{}", staffId, reqDeviceId);
        if (StringUtils.isBlank(reqDeviceId)) {
        	LOGGER.error("SystemController validDeviceId deviceId is empty staffId:{}", staffId);
            ret.setError(ErrorCodeConstants.ERR_0024, ErrorCodeConstants.ERR_MAP);
            return setGsonView(ret);
        }
        
        StoreManBindDeviceInfo cacheDeviceInfo = systemService.getCacheDeviceInfo(staffId);
        if (null == cacheDeviceInfo) {
            // 店员原先没有绑定设备ID
            LOGGER.error("SystemController validDeviceId no bind device. staffId:{}, deviceId:{}", staffId, reqDeviceId);
            ret.setError(ErrorCodeConstants.ERR_0023, ErrorCodeConstants.ERR_MAP);
        } else {
            // 店员原来有绑定设备ID
            if (!reqDeviceId.equals(cacheDeviceInfo.getDeviceId())) {
                // 设备ID不一致
            	LOGGER.error("SystemController validDeviceId not same bind device. staffId:{}, deviceId:{}", staffId, reqDeviceId);
            	try {
            		// 当前用户是否锁定
	            	boolean isLock = bindDeviceService.queryBindsIn7days(staffId);
	            	// 当前用户是否在白名单
	            	boolean isWhite = bindDeviceService.queryWhitelistStatus(staffId);
	            	if (isLock && !isWhite) {
	            		// 工号已锁定且不在白名单
	            		LOGGER.error("SystemController validDeviceId staffId({}) is locked", staffId);
	            		ret.setError(ErrorCodeConstants.ERR_0049, ErrorCodeConstants.ERR_MAP);
	            	} else {
	            		// 工号未锁定
	            		LOGGER.error("SystemController validDeviceId staffId({}) don't bind current device", staffId);
	            		// 查询帐号已绑定设备信息
	            		ret.setError(ErrorCodeConstants.ERR_0022, ErrorCodeConstants.ERR_MAP);
	            		MyGsonView gsonView = setGsonView(ret);
	            		gsonView.addStaticAttribute("deviceId", cacheDeviceInfo.getDeviceId());
	            		gsonView.addStaticAttribute("deviceName", cacheDeviceInfo.getDeviceName());
	            		gsonView.addStaticAttribute("bindTime", cacheDeviceInfo.getBindTime());
	            		return gsonView;
	            	}
            	} catch (Exception e) {
        			ret.setError(ModelErrorConstant.MODEL_ERR_E999, ModelErrorConstant.MODEL_ERR_MAP);
        			LOGGER.error(String.format("SystemController validDeviceId param(staffId:%s,deviceId:%s)", 
        					staffId, reqDeviceId), e);
        		}
            }
            // 当前设备和绑定设备一致则校验通过，此处不需处理
        }
        
	    return setGsonView(ret);
	}
	
	/**
	 * 
	 * 功能描述: 查询店员手机号信息<br>
	 * 〈功能详细描述〉
	 *
	 * @param principal
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	@RequestMapping("/queryStoreManMobile.do")
	public MyGsonView queryStoreManMobile(Principal principal) {
	    ReturnMsg<StoreManMoible> returnMsg = systemService.queryStoreManMobile(principal.getName());
	    return setGsonView(returnMsg);
	}
	
	/**
	 * 
	 * 功能描述: 发送设备绑定短信验证码<br>
	 * 〈功能详细描述〉
	 *
	 * @param mobileType
	 * @param principal
	 * @param request
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	@RequestMapping("/sendDeviceSms.do")
	public MyGsonView sendDeviceSms(String mobileType, Principal principal, HttpServletRequest request) {
	    String requestIp = getUserIp(request);
	    ReturnMsg<String> returnMsg = systemService.sendDeviceSms(principal.getName(), requestIp, mobileType);
	    return setGsonView(returnMsg);
	}
	
	/**
     * 
     * 功能描述: 取请求IP<br>
     * 〈功能详细描述〉
     *
     * @param request
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private String getUserIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (hasDeepIp(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (hasDeepIp(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (hasDeepIp(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (hasDeepIp(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (hasDeepIp(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
	
    /**
     * 
     * 功能描述: 判断IP是否OK<br>
     * 〈功能详细描述〉
     *
     * @param ip
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private boolean hasDeepIp(String ip) {
        return ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip);
    }
    
	/**
	 * 
	 * 功能描述: 校验设备ID校验码，成功绑定设备ID<br>
	 * 〈功能详细描述〉
	 *
	 * @param principal
	 * @param deviceName
	 * @param djDeviceId
	 * @param validCode
	 * @param mobileType
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	@RequestMapping("/validDeviceSms.do")
	public MyGsonView validDeviceSms(Principal principal, String deviceName, String djDeviceId, 
	        String validCode, String mobileType, HttpServletRequest request) {
	    Object[] args = {principal.getName(), mobileType, validCode, deviceName, djDeviceId};
	    LOGGER.info("validDeviceSms staffId:{}, mobileType:{}, validCode:{}, deviceName:{}, djDeviceId:{}", args);
	    
	    String ip = getUserIp(request);
	    
	    String staffId = principal.getName();
	    String deviceId = AESUtils.decodeAndDecrypt(djDeviceId, ConfigConstants.AES_KEY);
	    
	    ReturnMsg<CommonRtn> ret = new ReturnMsg<CommonRtn>();
	    if (bindDeviceService.staffIsLock(staffId, deviceId) 
	    		&& !bindDeviceService.queryWhitelistStatus(staffId)) {
	    	// 当前帐号已被锁定且不在白名单
	    	ret.setError(ErrorCodeConstants.ERR_0055, ErrorCodeConstants.ERR_MAP);
	    	return setGsonView(ret);
	    }
	    
	    BindRecordDto bindRecordDto = bindDeviceService.queryCurrBindInfo(staffId);
	    if (bindRecordDto != null 
	    		&& bindRecordDto.getDeviceId() != null  
	    		&& bindRecordDto.getDeviceId().equals(deviceId)) {
	    	// 当前设备是当前帐号已绑定设备
	    	ret.setError(ErrorCodeConstants.ERR_0057, ErrorCodeConstants.ERR_MAP);
	    	return setGsonView(ret);
	    }
	    
	    StoreManDto staffInfo = storeManService.queryStoreManAttachInfo(staffId);
	    ReturnMsg<String> returnMsg = systemService.validDeviceSms(staffId, staffInfo, 
	    		mobileType, validCode, deviceName, deviceId, ip);
        return setGsonView(returnMsg);
	}
	
	/**
	 * 查询请求协议类型http,https(默认)
	 * 功能描述: <br>
	 * 〈功能详细描述〉
	 *
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	@RequestMapping("/getRequestProtocol.htm")
    public MyGsonView getRequestProtocol() {
	    ReturnMsg<String> returnMsg = new ReturnMsg<String>();
	    // 默认https
	    String protocol = SCMConfigUtil.getConfig("request_protocol", "https");
        if ("http".equals(protocol)) {
            returnMsg.setData("0");
        } else {
            returnMsg.setData("1");
        }
	    return setGsonView(returnMsg);
    }
}
